package com.ktgj.customer.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.ktgj.customer.domain.BankCard;
import com.ktgj.customer.domain.Customer;
import com.ktgj.customer.domain.Employee;
import com.ktgj.customer.domain.vo.*;
import com.ktgj.customer.mapper.BankCardMapper;
import com.ktgj.customer.mapper.CustomerMapper;
import com.ktgj.customer.mapper.EmployeeMapper;
import com.ktgj.customer.service.ILoginService;
import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ktgj.customer.mapper.DepositBusinessMapper;
import com.ktgj.customer.domain.DepositBusiness;
import com.ktgj.customer.service.IDepositBusinessService;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;

/**
 * 预留款业务
Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-07-27
 */
@Transactional
@Service
public class DepositBusinessServiceImpl implements IDepositBusinessService
{
    @Autowired
    private DepositBusinessMapper depositBusinessMapper;
    @Autowired
    private BankCardMapper bankCardMapper;
    @Autowired
    private ILoginService loginService;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private CustomerMapper customerMapper;

    /**
     * 查询预留款业务
     *
     * @param businessId 预留款业务
     *                   ID
     * @return 预留款业务
     */
    @Override
    public DepositBusiness selectDepositBusinessById(Long businessId)
    {
        return depositBusinessMapper.selectDepositBusinessById(businessId);
    }

    /**
     * 查询预留款业务
     * 列表
     *
     * @param depositBusiness 预留款业务
     * @return 预留款业务
     */
    @Override
    public List<DepositBusiness> selectDepositBusinessList(DepositBusiness depositBusiness)
    {
        return depositBusinessMapper.selectDepositBusinessList(depositBusiness);
    }

    /**
     * 新增预留款业务
     *
     * @param depositBusiness 预留款业务
     * @return 结果
     */
    @Override
    public Long insertDepositBusiness(DepositBusiness depositBusiness)
    {
        int i = depositBusinessMapper.insertDepositBusiness(depositBusiness);
        if (i <= 0)
        {
            return 0l;
        } else
        {
            return depositBusiness.getBusinessId();
        }
    }

    /**
     * 修改预留款业务
     *
     * @param depositBusiness 预留款业务
     * @return 结果
     */
    @Override
    public int updateDepositBusiness(DepositBusiness depositBusiness)
    {
        return depositBusinessMapper.updateDepositBusiness(depositBusiness);
    }

    /**
     * 批量删除预留款业务
     *
     * @param businessIds 需要删除的预留款业务
     *                    ID
     * @return 结果
     */
    @Override
    public int deleteDepositBusinessByIds(Long[] businessIds)
    {
        return depositBusinessMapper.deleteDepositBusinessByIds(businessIds);
    }

    /**
     * 删除预留款业务
     * 信息
     *
     * @param businessId 预留款业务
     *                   ID
     * @return 结果
     */
    @Override
    public int deleteDepositBusinessById(Long businessId)
    {
        return depositBusinessMapper.deleteDepositBusinessById(businessId);
    }

    /**
     * 查询用户可用预留款
     *
     * @param customerId
     * @return
     */
    @Override
    public BigDecimal queyUserDepositBusiness(Long customerId)
    {
        List<BigDecimal> bigDecimals = depositBusinessMapper.queryUseDepositBusiness(customerId);
        if (bigDecimals != null && bigDecimals.size() > 0)
        {
            return bigDecimals.get(0);
        } else
        {
            return new BigDecimal(0);
        }
    }

    /**
     * 我的资产
     */
    @Override
    public DepositBusinessVo selectDepositBusinessByCustomerId(Long customerId, String operationtime)
    {
        List<DepositBusiness> depositBusinessList = depositBusinessMapper.selectDepositBusinessByCustomerId(customerId);//查询会员所有金币信息
        DepositBusinessVo depositBusinessVo = new DepositBusinessVo();//返回对象
        List<DepositBusinessDetailVo> depositBusinessDetailVoList = new CopyOnWriteArrayList<>();//预留款明细集合

        BigDecimal totalPoints = new BigDecimal(0l);//总金币
        String earnPoints;//可提现
        BigDecimal spendingPoints = new BigDecimal(0l);//冻结

        SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
        SimpleDateFormat monthFormat = new SimpleDateFormat("MM");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        String yearDate = operationtime.substring(0, 4);
        String monthDate = operationtime.substring(5, 7);

        //获取指定年月的金币流动记录
        for (DepositBusiness depositBusiness : depositBusinessList)
        {
            String year = yearFormat.format(depositBusiness.getOperationtime());
            String month = monthFormat.format(depositBusiness.getOperationtime());

            if (depositBusiness.getLockState().equals("false"))
            {//判断金币为解锁状态
                if (depositBusiness.getChangetype() == 2)
                {//计算支出金币
                    totalPoints = totalPoints.subtract(depositBusiness.getDetailamount());
                } else if (depositBusiness.getChangetype() == 1)
                {//计算获取金币
                    totalPoints = totalPoints.add(depositBusiness.getDetailamount());
                }

                if (year.equals(yearDate) && month.equals(monthDate))
                {//将年和月与参数对比，结果为true时证明该数据符合条件
                    DepositBusinessDetailVo depositBusinessDetailVo = new DepositBusinessDetailVo();
                    depositBusinessDetailVo.setOperationtime(format.format(depositBusiness.getOperationtime()));
                    depositBusinessDetailVo.setRemark(depositBusiness.getRemark());

                    if (depositBusiness.getLockState().equals("false"))
                    {//条件下判断金币为解锁状态
                        if (depositBusiness.getChangetype() == 2)
                        {//条件下计算支出金币
                            depositBusinessDetailVo.setDetailamount("-" + depositBusiness.getDetailamount());
                        } else if (depositBusiness.getChangetype() == 1)
                        {//条件下计算获取金币
                            depositBusinessDetailVo.setDetailamount("+" + depositBusiness.getDetailamount());
                        }
                    }
                    depositBusinessDetailVoList.add(depositBusinessDetailVo);
                }
            } else
            {
                spendingPoints = spendingPoints.add(depositBusiness.getDetailamount());//冻结金额
            }
        }
        earnPoints = String.valueOf((totalPoints.longValue()) / 10);//可提现金额

        List<BankCard> bankCardList = bankCardMapper.selectBankCardCountByMemberId(customerId);
        depositBusinessVo.setBankCardNumber(bankCardList.size() - 1);//银行卡数量
        depositBusinessVo.setCustomerId(customerId);
        depositBusinessVo.setAmount(totalPoints);
        depositBusinessVo.setAvailableGoldCoins(earnPoints + "0.00");
        depositBusinessVo.setUnAvailableGoldCoins(spendingPoints);
        depositBusinessVo.setDepositBusinessDetailVoList(depositBusinessDetailVoList);
        depositBusinessVo.setOperationtime(operationtime.substring(0, 4) + "年" + operationtime.substring(5) + "月");
        return depositBusinessVo;
    }


    @Override
    public boolean depositAudit(Long id, String remark)
    {
        DepositBusiness depositBusiness = depositBusinessMapper.selectDepositBusinessById(id);
        depositBusiness.setState("true");
        depositBusinessMapper.updateDepositBusiness(depositBusiness);
        DepositBusiness queryDeposit = new DepositBusiness();
        queryDeposit.setCustomerId(depositBusiness.getCustomerId());
        List<DepositBusiness> lstDeposit;
        lstDeposit = depositBusinessMapper.selectDepositBusinessList(queryDeposit);
        BigDecimal amount = new BigDecimal(0);
        if (lstDeposit.size() > 1)
        {
            for (DepositBusiness tmpDeposit : lstDeposit)
            {
                if (tmpDeposit.getAmount().intValue() > 0)
                {
                    amount = tmpDeposit.getAmount();
                    break;
                }
            }
        }
        int rows = 0;
        if (depositBusiness != null)
        {
            if (depositBusiness.getChangetype() == 1)
            {
                DepositBusiness tmpDeposit = new DepositBusiness();
                tmpDeposit.setCustomerId(depositBusiness.getCustomerId());
                tmpDeposit.setAmount(new BigDecimal(amount.intValue() + depositBusiness.getDetailamount().intValue()));
                rows = depositBusinessMapper.updateDepositByCustomerId(tmpDeposit);
            } else
            {
                DepositBusiness tmpDeposit = new DepositBusiness();
                tmpDeposit.setCustomerId(depositBusiness.getCustomerId());
                tmpDeposit.setAmount(new BigDecimal(amount.intValue() - depositBusiness.getDetailamount().intValue()));
                rows = depositBusinessMapper.updateDepositByCustomerId(tmpDeposit);
            }
        }
        if (rows > 0)
        {
            return true;
        }
        return false;
    }

    /**
     * 预留款审核
     */
    @Override
    public boolean goldCoinAudit(Long employeeId, Long id, String remark) throws Exception
    {
        boolean flag = false;
        Date date = new Date();

        DepositBusiness depositBusiness = depositBusinessMapper.selectDepositBusinessById(id);
        if (depositBusiness != null)
        {
            depositBusiness.setState("true");
            depositBusiness.setAuditor(employeeId);
            depositBusiness.setAuditingtime(date);

            if (depositBusiness.getChangetype() == 2)
            {
                depositBusiness.setAuditingremark(remark + "花费" + depositBusiness.getDetailamount());
            } else
            {
                depositBusiness.setAuditingremark(remark);
            }

            int i = depositBusinessMapper.updateDepositBusiness(depositBusiness);
            if (i <= 0)
            {
                throw new Exception("审核失败");
            }

            if (depositBusiness.getChangetype() == 2)
            {
                List<DepositBusiness> depositBusinessList = depositBusinessMapper.businessByCustomerId(depositBusiness.getCustomerId());
                if (depositBusinessList != null && depositBusinessList.size() > 0)
                {
                    //取出现在会员有的预留款列表
                    for (DepositBusiness business : depositBusinessList)
                    {
                        if (depositBusiness.getDetailamount().compareTo(new BigDecimal(0)) == 1)
                        {
                            if (business.getDetailamount().compareTo(depositBusiness.getDetailamount()) == -1)
                            {
                                depositBusiness.setDetailamount(depositBusiness.getDetailamount().subtract(business.getDetailamount()));
                                business.setDetailamount(new BigDecimal(0));
                                business.setChangetype(2l);
                                depositBusiness.setAuditingremark(remark + "花费" + business.getDetailamount());

                            } else
                            {
                                business.setDetailamount(business.getDetailamount().subtract(depositBusiness.getDetailamount()));
                                depositBusiness.setDetailamount(new BigDecimal(0));
                                depositBusiness.setAuditingremark(remark + "花费" + depositBusiness.getDetailamount());
                                if (business.getDetailamount().compareTo(new BigDecimal(0)) == 0)
                                {
                                    business.setChangetype(2l);
                                }
                            }
                            depositBusinessMapper.updateDepositBusiness(business);
                        }
                    }
                }
            }

            BigDecimal bigDecimal = goldStatistics(depositBusiness.getCustomerId());
            if (depositBusiness.getAmount() != null && bigDecimal.compareTo(new BigDecimal(-1)) >= 1)
            {
                depositBusiness.setAmount(depositBusiness.getAmount().add(bigDecimal));
            } else
            {
                depositBusiness.setAmount(bigDecimal);
            }
            i = depositBusinessMapper.updateDepositBusinessByCustomerId(depositBusiness);
            if (i > 0)
            {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 预留款统计
     */
    @Override
    public BigDecimal goldStatistics(Long id) throws Exception
    {
        BigDecimal amount = new BigDecimal(0);
        List<DepositBusiness> depositBusinessList = depositBusinessMapper.depositBusinessByCustomerId(id);
        if (depositBusinessList != null && depositBusinessList.size() > 0)
        {
            for (DepositBusiness depositBusiness : depositBusinessList)
            {
                if (depositBusiness.getChangetype() == 1)
                {
                    amount = amount.add(depositBusiness.getDetailamount());
                } else if (depositBusiness.getChangetype() == 2)
                {
                    amount = amount.subtract(depositBusiness.getDetailamount());
                } else
                {
                    throw new Exception("无效的变动方向");
                }
            }
        } else
        {
            return new BigDecimal(-1);
        }
        return amount;
    }

    /**
     * 预留款列表
     */
    @Override
    public List<DepositBusiness> goldList(GoldListVo goldListVo)
    {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<DepositBusiness> depositBusinessList = depositBusinessMapper.goldList(goldListVo);
        if (depositBusinessList != null && depositBusinessList.size() > 0)
        {
            for (DepositBusiness depositBusiness : depositBusinessList)
            {
                Customer customer = customerMapper.selectCustomerById(depositBusiness.getCustomerId());
                if (customer != null)
                {
                    depositBusiness.setCustomerName(customer.getCustomerName());
                    depositBusiness.setPhone(customer.getContractPhoneOne());
                }

                if (depositBusiness.getCreateTime() != null)
                {
                    depositBusiness.setOperationDate(format.format(depositBusiness.getCreateTime()));
                }
                if (depositBusiness.getAuditingtime() != null)
                {
                    depositBusiness.setAuditingDate(format.format(depositBusiness.getAuditingtime()));
                }
                Employee employee = employeeMapper.backSelectEmployee(depositBusiness.getOperatorId());
                if (employee != null)
                {
                    depositBusiness.setOperapersonName(employee.getEmployeeName());
                }
                Employee backSelectEmployee = employeeMapper.backSelectEmployee(depositBusiness.getAuditor());
                if (backSelectEmployee != null)
                {
                    depositBusiness.setAuditorName(backSelectEmployee.getEmployeeName());
                }
            }
        }
        return depositBusinessList;
    }


    /**
     * 预留款调整
     */
    @Override
    public int goldAdjustment(HttpServletRequest request, DepositBusiness depositBusiness) throws Exception
    {
        Employee loginEmployee = loginService.getLoginEmployee(request);
        if (loginEmployee == null)
        {
            throw new Exception("登陆已过期");
        }
        depositBusiness.setOperatorId(loginEmployee.getEmployeeId());
        depositBusiness.setCreateTime(new Date());
        depositBusiness.setState("false");
        List<DepositBusiness> lstDeposit;
        DepositBusiness queryDeposit = new DepositBusiness();
        queryDeposit.setCustomerId(depositBusiness.getCustomerId());
        lstDeposit = depositBusinessMapper.selectDepositBusinessList(queryDeposit);
        if (lstDeposit.size() == 0)
        {
            depositBusiness.setAmount(depositBusiness.getDetailamount());
        }else
        {
            depositBusiness.setAmount(new BigDecimal(0));
        }
        int i = depositBusinessMapper.insertDepositBusiness(depositBusiness);
        return i;
    }

    /**
     * 当前会员可支配预留款
     */
    @Override
    public BigDecimal dominateGold(Long id)
    {
        BigDecimal amount = new BigDecimal(0);
        List<DepositBusiness> depositBusinessList = depositBusinessMapper.dominateGold(id);
        if (depositBusinessList != null && depositBusinessList.size() > 0)
        {
            amount = depositBusinessList.get(0).getAmount();
            for (DepositBusiness depositBusiness : depositBusinessList)
            {
                if (depositBusiness.getState().equals("false") && depositBusiness.getChangetype() == 2)
                {
                    amount = amount.subtract(depositBusiness.getDetailamount());
                }
            }
        }
        return amount;
    }

    /**
     * 订单号查预留款记录
     */
    @Override
    public boolean audit(String orderNum)
    {
        List<DepositBusiness> audit = depositBusinessMapper.audit(orderNum);
        if (audit != null && audit.size() > 0)
        {
            for (DepositBusiness depositBusiness : audit)
            {
                if (depositBusiness.getChangetype() == 2)
                {
                    return false;
                } else
                {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean spendDeposit(DepositInfo depositInfo)
    {
        Long customerId = depositInfo.getCustomerId();
        BigDecimal depositAmount = depositInfo.getDepositCount();
        DepositBusiness depositUnapprove = new DepositBusiness();
        depositUnapprove.setState("false");
        depositUnapprove.setCustomerId(depositInfo.getCustomerId());
        List<DepositBusiness> lstUnAuditDeposit = depositBusinessMapper.selectDepositBusinessList(depositUnapprove);
        if (lstUnAuditDeposit.size() > 0)
        {
            throw new RuntimeException("存在未审核的预留款！");
        }
        DepositBusiness queryDeposit = new DepositBusiness();
        List<DepositBusiness> lstAllDeposit = depositBusinessMapper.selectDepositBusinessList(queryDeposit);
        List<DepositBusiness> lstInc = lstAllDeposit.stream().filter(item -> item.getChangetype() == 1).collect(Collectors.toList());
        List<DepositBusiness> lstDec = lstAllDeposit.stream().filter(item -> item.getChangetype() == 2).collect(Collectors.toList());
        int totalDeposit = getDepositValue(lstInc).intValue() - getDepositValue(lstDec).intValue();
        if (totalDeposit < depositInfo.getDepositCount().intValue())
        {
            throw new RuntimeException("预留款余额不足！");
        }
        List<DepositBusiness> lstDepoist = depositBusinessMapper.businessByCustomerId(customerId);
        lstDepoist = lstDepoist.stream().sorted(Comparator.comparing(DepositBusiness::getCreateTime).reversed()).collect(Collectors.toList());
        BigDecimal oldDeposit = depositAmount;
        for (DepositBusiness depositBusiness : lstDepoist)
        {
            if (depositBusiness.getDetailamount().intValue() >= depositAmount.intValue())
            {
                depositBusiness.setDetailamount(depositBusiness.getDetailamount().subtract(depositAmount));
                depositAmount = new BigDecimal(0);
            }
            if (depositBusiness.getDetailamount().intValue() < depositAmount.intValue())
            {
                depositAmount = depositAmount.subtract(depositBusiness.getDetailamount());
                depositBusiness.setDetailamount(new BigDecimal(0));
                depositBusinessMapper.updateDepositBusiness(depositBusiness);
            }
            if (depositAmount.intValue() == 0)
            {
                depositBusinessMapper.updateDepositBusiness(depositBusiness);
                DepositBusiness subDeposit = new DepositBusiness();
                subDeposit.setCustomerId(customerId);
                subDeposit.setAmount(depositBusiness.getAmount().subtract(oldDeposit));
                depositBusinessMapper.updateDepositBusinessByCustomerId(subDeposit);
                break;
            }
        }
        if (depositAmount.intValue() == 0)
        {
            return true;
        }
        return false;
    }

    public BigDecimal getDepositValue(List<DepositBusiness> lstData)
    {
        BigDecimal value = new BigDecimal(0);
        for (DepositBusiness depositBusiness : lstData)
        {
            if (depositBusiness.getDetailamount() != null)
            {
                value = value.add(depositBusiness.getDetailamount());
            }
        }
        return value;
    }
}